package com.youlai.system.global;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.youlai.system.controller.WebsocketController;
import com.youlai.system.helper.ApplicationContextHelper;
import com.youlai.system.model.entity.EventData;
import com.youlai.system.service.EventDataService;
import lombok.RequiredArgsConstructor;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@RequiredArgsConstructor
public class EventHandler {

    private static final EventDataService eventDataService = ApplicationContextHelper.getBean(EventDataService.class);

    public static enum MessageType {
        MESSAGE(1),
        WARNING(2),
        FAULT(3);

        private final int value;

        MessageType(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }

        public static MessageType fromValue(int value) {
            for (MessageType type : MessageType.values()) {
                if (type.getValue() == value) {
                    return type;
                }
            }
            throw new IllegalArgumentException("Invalid message type value: " + value);
        }

        @Override
        public String toString() {
            return name().charAt(0) + name().substring(1).toLowerCase();
        }
    }
    public static enum DeviceGroup {
        GROUP1(1, "组1"),
        GROUP2(2, "组2"),
        GROUP3(3, "组3"),
        GROUP4(4, "组4"),
        GROUP5(5, "组5"),
        GROUP6(6, "组6"),
        GROUP7(7, "组7"),
        GROUP8(8, "组8"),
        GROUP9(9, "组9"),
        GROUP10(10, "组10");

        private final int value;
        private final String description;

        DeviceGroup(int value, String description) {
            this.value = value;
            this.description = description;
        }

        public int getValue() {
            return value;
        }

        public String getDescription() {
            return description;
        }

        public static DeviceGroup fromValue(int value) {
            for (DeviceGroup group : DeviceGroup.values()) {
                if (group.getValue() == value) {
                    return group;
                }
            }
            throw new IllegalArgumentException("Invalid device group value: " + value);
        }

        @Override
        public String toString() {
            return description;
        }
    }
    public static enum Type {
        ADDRESS("地址"),
        DEVICE("设备"),
        OTHER("其他");

        private final String description;

        Type(String description) {
            this.description = description;
        }

        public String getDescription() {
            return description;
        }

        @Override
        public String toString() {
            return description;
        }
    }
    public static boolean Add(String name,Type type,DeviceGroup deviceGroup,String address,String code,MessageType messageType,String description){
        EventData eventData  = new EventData();

        eventData.setName(name);
        eventData.setType(type.getDescription());
        eventData.setDeviceGroup(deviceGroup.getDescription());
        eventData.setAddress(address);
        eventData.setCode(code);
        eventData.setStatus(messageType.getValue());
        eventData.setDescription(description);
        Boolean isOK = eventDataService.save(eventData);
        //上报消息
        WebsocketController websocketController = ApplicationContextHelper.getBean(WebsocketController.class);
        websocketController.reportEventToWebSocket(eventDataService.getEventDataBtnVO());
//        websocketController.reportEventToWebSocketEventCount(getMonthlyEventCountsToArray());
//        List<Map<String, Object>>  data = getMonthlyEventCountsToJSON();
//        List<Map<String, Object>> data2 = getMonthlyEventCountsToArray() ;
//        System.out.println(data);
//        System.out.println(data2);

        return isOK;
    }


    /**
     * 数据库事件记录
     */
    public static List<Map<String, Object>> getMonthlyEventCountsToJSON() {
        // 获取当前月份的第一天和最后一天
        LocalDate now = LocalDate.now();
        LocalDate firstDayOfMonth = now.withDayOfMonth(1);
        LocalDate lastDayOfMonth = now.withDayOfMonth(now.lengthOfMonth());

        // 生成本月每一天的日期列表
        List<LocalDate> dates = new ArrayList<>();
        for (LocalDate date = firstDayOfMonth; !date.isAfter(lastDayOfMonth); date = date.plusDays(1)) {
            dates.add(date);
        }

        // 查询本月每天的报警数量
        LambdaQueryWrapper<EventData> wrapper = new LambdaQueryWrapper<EventData>()
                .ge(EventData::getTime, firstDayOfMonth.atStartOfDay())
                .lt(EventData::getTime, lastDayOfMonth.plusDays(1).atStartOfDay())
                .select(EventData::getTime, EventData::getStatus);

        List<EventData> events = eventDataService.list(wrapper);

        // 统计每天的事件、警告和故障数量
        Map<LocalDate, Map<Integer, Integer>> countMap = new HashMap<>();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        for (EventData event : events) {
            LocalDateTime eventDateTime = LocalDateTime.parse(event.getTime(), formatter);
            LocalDate eventDate = eventDateTime.toLocalDate();
            int status = event.getStatus();

            countMap.putIfAbsent(eventDate, new HashMap<>());
            Map<Integer, Integer> statusCount = countMap.get(eventDate);
            statusCount.put(status, statusCount.getOrDefault(status, 0) + 1);
        }

        // 构建结果列表
        List<Map<String, Object>> result = new ArrayList<>();
        for (LocalDate date : dates) {
            Map<String, Object> dayData = new HashMap<>();
            dayData.put("date", date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            dayData.put("events", countMap.getOrDefault(date, Collections.emptyMap()).getOrDefault(1, 0));
            dayData.put("warnings", countMap.getOrDefault(date, Collections.emptyMap()).getOrDefault(2, 0));
            dayData.put("faults", countMap.getOrDefault(date, Collections.emptyMap()).getOrDefault(3, 0));
            result.add(dayData);
        }

        return result;
    }




}
